package cn.edu.nju.ws.sview.views.data;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;

import cn.edu.nju.ws.ocr.api.Coref;
import cn.edu.nju.ws.ocr.util.Inst;
import cn.edu.nju.ws.ocr.util.RDFStmt;
import cn.edu.nju.ws.sview.LogManagement;
import cn.edu.nju.ws.sview.cache.FalconURIIDCache;
import cn.edu.nju.ws.sview.cache.URIIDCache;
import cn.edu.nju.ws.sview.cache.URILabelCache;
import cn.edu.nju.ws.sview.cache.UserNameIDCache;
import cn.edu.nju.ws.sview.crawler.Crawler;
import cn.edu.nju.ws.sview.crawler.Element;
import cn.edu.nju.ws.sview.database.DBConnectionFactory;
import cn.edu.nju.ws.sview.database.DBOperations;
import cn.edu.nju.ws.sview.rdf.ResourceFactory;
import cn.edu.nju.ws.sview.rdf.URIResource;
import cn.edu.nju.ws.sview.thirdparty.FalconObjectSearch;
import cn.edu.nju.ws.sview.thirdparty.FalconObjectSearch.Instance;
import cn.edu.nju.ws.sview.util.SwitchSViewFalcons;
import cn.edu.nju.ws.sview.util.URIUtil;
import cn.edu.nju.ws.sview.views.CustomCollection;
import cn.edu.nju.ws.sview.views.Entity;

/**
 * 管理原始URI,收藏实体，收藏集合的流行度
 * 
 * 
 * 删除一个实体操作须处理：
 *    1.删除user_day_visit中信息
 *    2.删除user_visit中信息
 *    
 * 更新访问频率需要
 *    1.更新user_day_visit中信息
 *    2.更新user_visit中信息
 *    3.更新visit_lang中信息
 * @author gongsaisai
 *
 */
public class EntityManagement extends Management{
   public final static String CLEAR_ENTITY_POPULARITY = "clear_entity_pop" ;
   public final static String CLEAR_TMP_COLLECTION = "clear_tmp_collection";
   public final static double SAMEAS_SCORE_WEIGHT ;
   public final static double GROUP_SCORE_WEIGHT ;
   public final static int RECOMMEND_NUM = 5;
   public final static int MAX_SNIPPET_TRIPLE_NUM = 5;
   
	static {
		Properties properties = new Properties();
		try {
			properties.load(EntityManagement.class.getClassLoader()
					.getResourceAsStream("conf.properties"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		SAMEAS_SCORE_WEIGHT =Double.parseDouble(properties.getProperty("sameAs_score_weight"));
		GROUP_SCORE_WEIGHT = Double.parseDouble(properties.getProperty("group_score_weight"));
		properties.clear();
	} 
	
   private static EntityManagement INSTANCE = null;
   private EntityManagement(){
	   
   }
   
   public static synchronized EntityManagement getInstance(){
	   if(INSTANCE==null)
		   INSTANCE = new EntityManagement();
	   return INSTANCE;
   }
   
  /**
   * 得到相对当前日子而言，前offet天数据对应的数据库user_day_visit中date值
   * 即数据库中仍然按照每天所属的周几存储，但是取每天之前的数据需要做转化
   * @param offset
   * @return
   */
   public  int getDateOfPast(int offset){
		int result = 0;
		//得到当前日期是周几
		int date = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)-1;
		result = date-offset +(date-offset>=0?0:7);
		return result;
	}
   
   public static void storeUserVisit(String userName,int etype,int eid, String lang){
		int userID = 0;
		if (userName != null) {
			try {
				userID = UserNameIDCache.getInstance().getUserID(userName);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		boolean flag = false;
		if (etype == Entity.COLLECTION) {
			flag = CustomCollection.isTmpCollection(etype, eid);
		}
		if (flag)
			return;
		LogManagement.storeLogVisit(userID, etype, eid, -1, lang);

		int status = checkStatus(userID, Management.CONTROL_ENTITY_TYPE, etype,
				eid);
		if (status == EntityManagement.UNVISITED) {

			EntityManagement.storeVisitInControl(userID, CONTROL_ENTITY_TYPE,
					etype, eid);
			userVisit(userID, etype, eid, lang);

		} else if (status == EntityManagement.VISITED_COUNT_INVALID) {
			return;
		} else if (status == EntityManagement.VISITED_COUNT_VALID) {
			EntityManagement.storeVisitInControl(userID, CONTROL_ENTITY_TYPE,
					etype, eid);
			userVisit(userID, etype, eid, lang);
		}
   }
   
   private static void userVisit(int userID,int etype,int eid, String lang){
//		System.out.println("userVisit:"+userID+"|"+etype+"|"+eid+"|"+lang);
	   try {
		Connection con = DBConnectionFactory.getConnection();
		int date = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)-1;
		PreparedStatement user_day_visit_stmt = con.prepareStatement(
				"insert into user_day_visit(user_id,member_type,member_id,date,times_recent) " +
				"values(?,?,?,?,?) on duplicate key update times_recent=times_recent+1");
		user_day_visit_stmt.setInt(1, userID) ;
		user_day_visit_stmt.setInt(2, etype);
		user_day_visit_stmt.setInt(3, eid) ;
		int times = 1;
		user_day_visit_stmt.setInt(4,date);
		user_day_visit_stmt.setInt(5, times) ;
		user_day_visit_stmt.executeUpdate();
		user_day_visit_stmt.close();
		
		PreparedStatement user_visit_stmt = con.prepareStatement(
				"insert into user_visit(user_id,member_type,member_id,times_total) " +
				"values(?,?,?,?) on duplicate key update times_total=times_total+1");
		user_visit_stmt.setInt(1, userID) ;
		user_visit_stmt.setInt(2, etype);
		user_visit_stmt.setInt(3, eid) ;
		user_visit_stmt.setInt(4, times) ;
		user_visit_stmt.executeUpdate();
		user_visit_stmt.close();
		
		PreparedStatement visit_lang = con.prepareStatement(
				"insert ignore into visit_lang(member_type,member_id,lang) values(?,?,?)");
		visit_lang.setInt(1,etype);
		visit_lang.setInt(2,eid);
		visit_lang.setString(3,lang);
		visit_lang.executeUpdate();
		visit_lang.close();
		con.close();
		
	} catch (Throwable e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	   
   }
   
  /**
   * get uri members of uri entity/single custom entity/collection
   * @param etype
   * @param eid
   * @param lang
   * @return
   */
   public ArrayList<URIMember> getURIMembersOfEntity(int etype,int eid,String lang){
		ArrayList<URIMember> result = new ArrayList<URIMember>();
		if (etype == Entity.URI_ENTITY) {
			URIResource r = null;
			try {
				r = ResourceFactory.getInstance().createURIResource(
						URIIDCache.getInstance().getURI(eid));
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			if (DBOperations.getValidStatus(eid) != URIResource.VALID
					&& Crawler.getInstance().checkStatus(r) == Crawler.STATUS_UNSUBMITTED) {
				Crawler.getInstance().submitURI(r);
				Crawler.getInstance().promoteWeight(r, Element.LEVEL_1);
				boolean waitflag = true;
				while (waitflag) {
					waitflag = false;
					int status = Crawler.getInstance().checkStatus(r);
					if (status != Crawler.STATUS_DONE) {
						waitflag = true;
						break;
					}
					try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

			String label = "";
			try {
				label = URILabelCache.getInstance().getLabel(eid, lang);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			if (label.equals("")) {
				label = URIUtil.getLocalname(r.getURI());
			}

			String uri = null;

			try {
				uri = URIIDCache.getInstance().getURI(eid);
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			URIMember e = new URIMember(eid, uri, label);
			result.add(e);
		} else {
			result.addAll(getIdentityMembers(etype, eid, lang));
		}
		return result;
   }
   
   
   /**
    * get uri memmber of an entity which must be custom single entity
    * @param etype
    * @param eid
    * @param lang
    * @return
    */
   public ArrayList<URIMember> getIdentityMembers(int etype,int eid,String lang){
	   if (etype != Entity.COLLECTION && etype != Entity.CUSTOM_ENTITY) {
			throw new IllegalArgumentException("The entity etype is invalid");
		}
		ArrayList<URIMember> result = new ArrayList<URIMember>();
		Connection con = DBConnectionFactory.getConnection();
		try {
			Statement stmt = con.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select uri_id from identity_entity where identity_id=%d ",
					eid));
			while(rs.next()){
				int uriID = rs.getInt("uri_id");
				URIResource r = null;
				try {
					r = ResourceFactory.getInstance().createURIResource(URIIDCache.getInstance().getURI(uriID));
				} catch (Throwable e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
	    		if(DBOperations.getValidStatus(uriID)!=URIResource.VALID&&
						Crawler.getInstance().checkStatus(r)==Crawler.STATUS_UNSUBMITTED){
	    			Crawler.getInstance().submitURI(r);
	    			Crawler.getInstance().promoteWeight(r, Element.LEVEL_1);
	        		boolean waitflag = true;
				    while(waitflag){
				    	waitflag =false;
				    	     int status = Crawler.getInstance().checkStatus(r) ;
				    	     if(status!=Crawler.STATUS_DONE){
				    	    	 waitflag = true;
				    	    	 break;
				    	     }
				    	 try {
							Thread.sleep(20);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
				    }
	    		}
	
				String label = "";
				try {
					label = URILabelCache.getInstance().getLabel(uriID, lang);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				if(label.equals("")){
					label = URIUtil.getLocalname(r.getURI()) ;
				}
				
				String uri = null;
				
				try {
					uri = URIIDCache.getInstance().getURI(uriID);
				} catch (Throwable e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				URIMember e= new URIMember(uriID,uri,label);
				result.add(e);
			}
			
			rs.close();
			stmt.close();
			con.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
   }
   
   public ArrayList<Entry<Integer, String>> getIdentityTypes(int etype,int eid,String lang){
		if (etype != Entity.COLLECTION && etype != Entity.CUSTOM_ENTITY) {
			throw new IllegalArgumentException("The entity etype is invalid");
		}
		ArrayList<Entry<Integer, String>> result = new ArrayList<Entry<Integer, String>>();
		Connection con = DBConnectionFactory.getConnection();
		try {
			Statement stmt = con.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select class_id from identity_type where identity_id=%d ",
					eid));
			while(rs.next()){
				int classID = rs.getInt("class_id");
				URIResource r = null;
				try {
					r = ResourceFactory.getInstance().createURIResource(URIIDCache.getInstance().getURI(classID));
				} catch (Throwable e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
	    		if(DBOperations.getValidStatus(classID)!=URIResource.VALID&&
						Crawler.getInstance().checkStatus(r)==Crawler.STATUS_UNSUBMITTED){
	    			Crawler.getInstance().submitURI(r);
	    			Crawler.getInstance().promoteWeight(r, Element.LEVEL_1);
	        		boolean waitflag = true;
				    while(waitflag){
				    	waitflag =false;
				    	     int status = Crawler.getInstance().checkStatus(r) ;
				    	     if(status!=Crawler.STATUS_DONE){
				    	    	 waitflag = true;
				    	    	 break;
				    	     }
				    	 try {
							Thread.sleep(20);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
				    }
	    		}
	
				String label = "";
				try {
					label = URILabelCache.getInstance().getLabel(classID, lang);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				if(label.equals("")){
					label = URIUtil.getLocalname(r.getURI()) ;
				}
				Entry<Integer,String> e= new SimpleEntry<Integer, String>(classID,label);
				result.add(e);
			}
			
			rs.close();
			stmt.close();
			con.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
   }
   
   /**
    * 查看对于原始uri，所在编辑组是否已经制作过自定义实体了
    * @param etype
    * @param eid
    * @param groupID
    * @param lang
    * @return -1 if not exist or the custom entity id
    */
   public int isCreated(int etype,int eid,int groupID,String lang){
	   int result = -1;
	   HashSet<Item> set = getRelatedMyGroupEntity(etype,eid,groupID,lang);
	   for(Item item:set){
		   result = item.getEID();
	   }
	   return result;
   }
   
   /**
    * get related entity of specific group(not collection). first fetch orgin uris of eid and see which identity have them as members
    * @param etype
    * @param eid
    * @param groupID
    * @param lang
    * @return 
    */
   public  HashSet<Item> getRelatedMyGroupEntity(int etype,int eid,int groupID,String lang){
	   HashSet<Item> result = new  HashSet<Item>();
	   HashSet<Integer> originURIs  = new HashSet<Integer>();
	   if(etype==Entity.URI_ENTITY){
		   originURIs.add(eid);
	   }else{
		   originURIs.addAll(Entity.getMembersByEntityId(eid));
	   }
		Connection con = DBConnectionFactory.getConnection();
		try {
            PreparedStatement stmt;
            {
            	stmt = con.prepareStatement("select type,identity_id from identity_entity,identity where identity_id = identity.id  and identity.group_id=? and  uri_id=? ");
            	stmt.setInt(1, groupID);
            }
			for(Integer uid:originURIs){
				stmt.setInt(2, uid);
				ResultSet rs = stmt.executeQuery();
				while(rs.next()){
					int identID = rs.getInt("identity_id");
					int type = rs.getInt("type");
					String name = Entity.getNameByEntityID(identID, lang);
					Item item = new Item(type,identID,name,groupID);
					result.add(item);
				}
				rs.close();
			}
            stmt.close();
            con.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
   }
   
   
   /**
    *From start,  get  specific num of recommended coreference entity of specific group in specific lang. first fetch orgin uris of eid and see which identity have them as members
    * @param etype
    * @param eid
    * @param groupID
    * @param lang
    * @param start. recommend start to (start+recommendNum) entity
    * @param result. contain all the recommended results
    * @return the total num of all recommend entities
    */
   public  int  getRecommendCorefEntity(int etype,int eid,Integer groupID,String lang,int start,ArrayList<RecomdItem> result){
		HashSet<Integer> originURIs = new HashSet<Integer>();
		if (etype == Entity.URI_ENTITY) {
			originURIs.add(eid);
		} else {
			originURIs.addAll(Entity.getMembersByEntityId(eid));
		}

		ArrayList<Integer> orderURIs = new ArrayList<Integer>(originURIs);
		Collections.sort(orderURIs);
		ArrayList<String> inputURIs = new ArrayList<String>();
		for (Integer uriID : orderURIs) {
			try {
				String uri = URIIDCache.getInstance().getURI(uriID);
				inputURIs.add(uri);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		List<Inst> list = Coref.getSameAsInstances(inputURIs);
		int end = (start+EntityManagement.RECOMMEND_NUM)<list.size()?(start+EntityManagement.RECOMMEND_NUM):list.size();
		for(int i=start;i<end;i++){
			Inst inst = list.get(i);
			RecomdItem ritem = null;
			
			int uriID = SwitchSViewFalcons.getSViewURIIDByFalconID(inst.getURIID());
			List<RDFStmt> stmts = inst.getReasoningProof();
			ArrayList<ArrayList<String>> snippet =new ArrayList<ArrayList<String>>();
			int count = 0;
			for(RDFStmt stmt:stmts){
				count++;
				if(count>MAX_SNIPPET_TRIPLE_NUM)
					break;
				String s= stmt.getSubject();
				String p = stmt.getPredicate();
				String o = stmt.getObject();
				ArrayList<String> triple = new ArrayList<String>();
				triple.add(s);
				triple.add(p);
				triple.add(o);
				snippet.add(triple);
			}
			
			ritem = new RecomdItem(uriID,snippet,true);
			result.add(ritem);
		}
		
		return list.size();
   }  
   
   /**
    *From start,  get  specific num of recommended coreference entity of specific group in specific lang. first fetch orgin uris of eid and see which identity have them as members
    * @param etype
    * @param eid
    * @param groupID
    * @param lang
    * @param start. recommend start to (start+recommendNum) entity
    * @param result. contain all the recommended results
    * @return the total num of all recommend entities
    */
   public  int  getFalconSearchEntity(String query,int start,ArrayList<RecomdItem> result){
		ArrayList<Instance> list = new ArrayList<Instance>();
		int totalNum = FalconObjectSearch.getResult(query, start, list);
		
		for(int i=0;i<list.size();i++){
			Instance inst = list.get(i);
			RecomdItem ritem = null;
			
			int uriID = inst.getURIID();
			ArrayList<ArrayList<String>> snippet  = inst.getSnippet();
			
			ritem = new RecomdItem(uriID,snippet,true);
			result.add(ritem);
		}
		
		return totalNum;
   }    
   
   public  void clearEntityPopularityRemainLang(){
		 Connection con = DBConnectionFactory.getConnection();
		 try {
			    Statement stmt = con.createStatement();
			    stmt.executeUpdate("delete from user_day_visit") ;
			    stmt.close();
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
		}
   }
   
   public void clearTmpCollection(){
	   try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery("select id,create_time from identity where group_id=-1");
			while(rs.next()){
				int id =rs.getInt("id");
				Date date =rs.getTimestamp("create_time");
		    	Date now = new Date();
		    	Calendar c1 =Calendar.getInstance();
		    	Calendar c2 = Calendar.getInstance();
		    	c1.setTime(date) ;
		    	c2.setTime(now) ;
		    	long difference = now.getTime()-date.getTime();
	    		/*为了防止正在使用的tmp collection正好遇上clear任务*/
	    		if(difference>0.5*60*60*1000){
	    			Entity.delete(Entity.COLLECTION,id);
	    		}
			}
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
   }
   
   public  void clearEntityPopularityAll(){
		 Connection con = DBConnectionFactory.getConnection();
		 try {
			    Statement stmt = con.createStatement();
			    stmt.executeUpdate("delete from user_day_visit") ;
			    stmt.executeUpdate("delete from visit_lang") ;
			    stmt.close();
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
 		}
  }
   
   /**
    * 根据falcon四元组表中的内容生成SView表中的内容
    * @param falconStr.以u或者l开头
    * @return. 
    */
   public static ArrayList<String> getSViewStr(String falconStr,String lang){
		ArrayList<String> result= new ArrayList<String>();
		if (falconStr.startsWith("u")) {
			int falconID = Integer.valueOf(falconStr.substring(1));
			try {
				String falconURI = FalconURIIDCache.getInstance().getURI(
						falconID);
				int myID = URIIDCache.getInstance().getURIID(falconURI, true);
				//如果falconStr以u开头，那么返回的第一个原始是id，第二个元素是其uri,第三个元素是其显示名称
				result.add(""+myID);
				result.add(falconURI);
		        
				String label = URILabelCache.getInstance().getLabel(myID, lang);
				if(label.equals("")){
					label = URIUtil.getLocalname(falconURI);
 				}
				result.add(label);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} else if (falconStr.startsWith("l")) {
			result.add(falconStr.substring(1));
		}
		return result;
   }   
   
	public static class URIMember {
		private int uriID;
		private String uriString;
		private String label;

		public URIMember(int uriID, String uriString, String label) {
			this.uriID = uriID;
			this.uriString = uriString;
			this.label = label;
		}
		
		public int getURIID(){
			return this.uriID;
		}
		
		public String getURI(){
			return this.uriString;
		}
		
		public String getLabel(){
			return this.label;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + uriID;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			URIMember other = (URIMember) obj;
			if (uriID != other.uriID)
				return false;
			return true;
		}

	}
   
   public static class Item{
	   private int etype;
	   private int eid;
	   private int gid;
	   private String name;
	   public Item(int etype,int eid,String name,int gid){
		   this.etype = etype;
		   this.eid = eid;
		   this.name = name;
		   this.gid = gid;
	   }
	   
	   public int getEType(){
		   return this.etype;
	   }
	   
	   public int getEID(){
		   return this.eid;
	   }
	   
	   public String getName(){
		   return this.name;
	   }
	   
	   public int getGroupID(){
		   return this.gid;
	   }

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + eid;
		result = prime * result + etype;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Item other = (Item) obj;
		if (eid != other.eid)
			return false;
		if (etype != other.etype)
			return false;
		return true;
	}
	   
   }
   
   public static class RecomdItem{
		private int uriID;
		
		private ArrayList<ArrayList<String>> snippet;
		
		//如果fromFalcons为true，那么最后显示snippet需要转成sview系统的id
		private boolean fromFalcons;

		public RecomdItem(int uriID,ArrayList<ArrayList<String>> snippet,boolean fromFalcons) {
			this.uriID = uriID;
			this.snippet = snippet;
			this.fromFalcons = fromFalcons;
		}
		
		public String getURI(){
			String uri = null;
			try {
				uri = URIIDCache.getInstance().getURI(this.uriID);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return uri;
		}
		
		public String getLabel(String lang){
			URIResource r = null;
			try {
				r = ResourceFactory.getInstance().createURIResource(
						this.getURI());
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			if (DBOperations.getValidStatus(this.getURIID()) != URIResource.VALID
					&& Crawler.getInstance().checkStatus(r) == Crawler.STATUS_UNSUBMITTED) {
				Crawler.getInstance().submitURI(r);
				Crawler.getInstance().promoteWeight(r, Element.LEVEL_1);
				boolean waitflag = true;
				while (waitflag) {
					waitflag = false;
					int status = Crawler.getInstance().checkStatus(r);
					if (status != Crawler.STATUS_DONE) {
						waitflag = true;
						break;
					}
					try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

			String label = "";
			try {
				label = URILabelCache.getInstance().getLabel(this.uriID, lang);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			if (label.trim().equals("")) {
				label = URIUtil.getLocalname(r.getURI());
			}
			
			return label;
		}
		
		public ArrayList<ArrayList<String>> getSnippet(){
			return this.snippet;
		}
		
		public int getURIID() {
			return this.uriID;
		}
		
		public boolean snippetIsFromFalcons(){
			return this.fromFalcons;
		}
		
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + uriID;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			RecomdItem other = (RecomdItem) obj;
			if (uriID != other.uriID)
				return false;
			return true;
		}
   }
}
